package com.momo.service.sysSetting;

import com.momo.common.common.JSONResult;
import com.momo.common.req.sysSetting.authority.AclModuleReq;
import com.momo.common.req.sysmain.RedisUser;
import com.momo.common.util.DateUtil;
import com.momo.common.util.LevelUtil;
import com.momo.common.util.RedisUtil;
import com.momo.common.util.StrUtil;
import com.momo.mapper.dataobject.AclModuleDO;
import com.momo.mapper.mapper.sysSetting.AclModuleMapper;
import com.momo.service.async.AclAsync;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.CollectionUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;

/**
 * Created by Kagome on 2019/3/19.
 */
@Service
@Slf4j
public class SysAclModuleServiceImpl implements SysAclModuleService {

    @Autowired
    private AclModuleMapper aclModuleMapper;
    @Autowired
    private RedisUtil redisUtil;
    @Autowired
    private AclAsync aclAsync;

    @Override
    @Transactional
    public JSONResult add(AclModuleReq aclModuleReq, RedisUser redisUser) {
        if (checkExists(aclModuleReq)) {
            return JSONResult.errorMap("同一层级下存在相同名称的权限模块");
        }
        AclModuleDO entity = new AclModuleDO();
        BeanUtils.copyProperties(aclModuleReq, entity);
        entity.setSysAclModuleLevel(LevelUtil.calculateLevel(getLevel(aclModuleReq.getSysAclModuleParentId()), aclModuleReq.getSysAclModuleParentId()));
        entity.setCreateBy(redisUser.getSysUserName());
        entity.setCreateTime(DateUtil.getDateTime());
        entity.setUpdateBy(redisUser.getSysUserName());
        entity.setUpdateTime(DateUtil.getDateTime());
        entity.setSysAclModuleUuid(StrUtil.genUUID());
        aclModuleMapper.insertSelective(entity);
        aclAsync.aclModuleToRedis(entity);
        return JSONResult.ok("新增权限模块成功");
    }

    @Override
    public JSONResult modify(AclModuleReq aclModuleReq, RedisUser redisUser) {
        AclModuleDO before = aclModuleMapper.selectByUUID(aclModuleReq.getSysAclModuleUuid());
        if (null == before) {
            return JSONResult.errorMap("待查询的权限模块不存在");
        }
        aclModuleReq.setId(before.getId());
        if (checkExists(aclModuleReq)) {
            return JSONResult.errorMap("同一层级下存在相同名称的权限模块");
        }
        if (before.getId().equals(aclModuleReq.getSysAclModuleParentId())) {
            return JSONResult.ok("无法将当前模块挂在自己模块下");
        }
        if (!before.getSysAclPermissionType().equals(aclModuleReq.getSysAclPermissionType())) {
            return JSONResult.errorMap("无法跨模块编辑");
        }
        AclModuleDO after = new AclModuleDO();
        BeanUtils.copyProperties(aclModuleReq, after);
        after.setId(before.getId());
        after.setSysAclModuleLevel(LevelUtil.calculateLevel(getLevel(aclModuleReq.getSysAclModuleParentId()), aclModuleReq.getSysAclModuleParentId()));
        after.setUpdateBy(redisUser.getSysUserName());
        after.setUpdateTime(DateUtil.getDateTime());
        updateWithChild(before, after);

        return JSONResult.ok("更新权限模块成功");
    }

    @Transactional
    @Override
    public JSONResult status(AclModuleReq aclModuleReq, RedisUser redisUser) {
        AclModuleDO before = aclModuleMapper.selectByUUID(aclModuleReq.getSysAclModuleUuid());
        if (null == before) {
            return JSONResult.errorMap("待查询的权限模块不存在");
        }
        String statusMsg = "";
        //状态 0启用  1禁用
        if ("0".equals(aclModuleReq.getSysAcModulelStatus())) {
            before.setSysAcModulelStatus("1");
            statusMsg = "权限模块状态 禁用 成功";
        } else if ("1".equals(aclModuleReq.getSysAcModulelStatus())) {
            before.setSysAcModulelStatus("0");
            statusMsg = "权限模块状态 启用 成功";
        }
        before.setUpdateBy(redisUser.getSysUserName());
        before.setUpdateTime(DateUtil.getDateTime());
        aclModuleMapper.updateByPrimaryKeySelective(before);
        aclAsync.aclModuleToRedis(before);
        return JSONResult.ok(statusMsg);
    }

    @Override
    public JSONResult detail(AclModuleReq aclModuleReq) {
        AclModuleDO aclModuleDO = aclModuleMapper.selectByUUID(aclModuleReq.getSysAclModuleUuid());
        if (null == aclModuleDO){
           return JSONResult.errorMap("待查询的权限模块不存在");
        }
        return JSONResult.ok(aclModuleDO);
    }

    @Transactional
    private void updateWithChild(AclModuleDO before, AclModuleDO after) {
        String newLevelPrefix = after.getSysAclModuleLevel();
        String oldLevelPrefix = before.getSysAclModuleLevel();
        List<AclModuleDO> aclModuleList = null;
        if (!after.getSysAclModuleLevel().equals(before.getSysAclModuleLevel())) {
            aclModuleList = aclModuleMapper.getChildAclModuleListByLevel(LevelUtil.calculateLevel(before.getSysAclModuleLevel(), before.getId()));
            if (CollectionUtils.isNotEmpty(aclModuleList)) {
                for (AclModuleDO aclModule : aclModuleList) {
                    String level = aclModule.getSysAclModuleLevel();
                    if (level.indexOf(oldLevelPrefix) == 0) {
                        level = newLevelPrefix + level.substring(oldLevelPrefix.length());
                        aclModule.setSysAclModuleLevel(level);
                    }
                }
                aclModuleMapper.batchUpdateLevel(aclModuleList);

            }
        }
        after.setSysAclPermissionType(null);
        aclModuleMapper.updateByPrimaryKeySelective(after);
        aclAsync.aclModuleToRedis(after);
        aclAsync.batchAclModuleToRedis(aclModuleList, before.getSysAclPermissionType());
    }

    private boolean checkExists(AclModuleReq aclModuleReq) {
        return aclModuleMapper.checkExists(aclModuleReq.getId(), aclModuleReq.getSysAclModuleParentId(), aclModuleReq.getSysAclModuleName()) > 0 ? true : false;
    }

    private String getLevel(Long aclModuleId) {
        AclModuleDO aclModule = aclModuleMapper.selectByPrimaryKey(aclModuleId);
        if (aclModule == null) {
            return null;
        }
        return aclModule.getSysAclModuleLevel();
    }

}
